home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
rayshade
/
libshade
/
fastimage.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
9KB
|
330 lines
/* from fastimage.c */
#include <stdio.h>
#include <gl/image.h>
static struct
{
FILE *ifile;
IMAGE header;
FILE *inf;
unsigned char *rledat, *verdat;
int rlebuflen;
long *starttab, *lengthtab;
}im;
SgiRgbOpen(name, type, xsize, ysize, zsize)
char *name;
int type;
int *xsize, *ysize, *zsize;
{
im.header = (IMAGE *)malloc(sizeof(IMAGE));
im.header->xsize = xsize;
im.header->ysize = ysize;
im.header->zsize = zsize;
im.header->type = type;
if(ISRLE(type))
{
im.tablen = ysize * zsize * sizeof(long);
im.starttab = (long *)malloc(im.tablen);
im.lengthtab = (long *)malloc(im.tablen);
im.rlebuflen = 1.05*xsize+10;
im.rledat = (unsigned char *)malloc(im.rlebuflen);
}
im.file = fopen(name,"w");
if(!im.file)
{
fprintf(stderr,"SgiRgbOpen: can't open SGI RGB file %s\n",name);
exit(1);
}
}
SgiRgbWriteLine()
{
}
SgiRgbClose()
{
int y,z;
fwrite(&im.header,sizeof(IMAGE),1,im.file);
fwrite(&im.header,sizeof(IMAGE),1,im.file);
fseek(im.file,512,SEEK_SET);
fwrite(im.starttab,im.tablen,1,im.file);
fwrite(im.lengthtab,im.tablen,1,im.file);
for(y = 0; y < im.header->ysize; y++)
{
for(z = 0; z < im.header->zsize; z++)
{
fseek(im.file, im.starttab[y+z*im.header->ysize], SEEK_SET);
fwrite(im.rledat, im.lengthtab[y+z*im.header->ysize], 1, im.file);
}
}
fclose(im.file);
}
/*
* longimagedata -
* read img a B/W RGB or RGBA iris image file and return a
* pointer to an array of longs.
*
*/
sgiRGBwrite()
char *name;
{
unsigned long *base, *lptr;
unsigned char *rledat, *verdat;
long *starttab, *lengthtab;
FILE *inf;
IMAGE *image;
int y, z, pos, len, tablen;
int xsize, ysize, zsize;
int bpp, rle, cur, badorder;
int rlebuflen;
inf = fopen(name,"r");
if(!inf) {
fprintf(stderr,"longimagedata: can't open image file %s\n",name);
exit(1);
}
fread(image,sizeof(IMAGE),1,inf);
if(image->imagic != IMAGIC) {
fprintf(stderr,"longimagedata: bad magic number in image file\n");
exit(1);
}
rle = ISRLE(image->type);
bpp = BPP(image->type);
if(bpp != 1 ) {
fprintf(stderr,"longimagedata: image must have 1 byte per pix chan\n");
exit(1);
}
xsize = image->xsize;
ysize = image->ysize;
zsize = image->zsize;
if(rle) {
tablen = ysize*zsize*sizeof(long);
starttab = (long *)malloc(tablen);
lengthtab = (long *)malloc(tablen);
rlebuflen = 1.05*xsize+10;
rledat = (unsigned char *)malloc(rlebuflen);
fseek(inf,512,SEEK_SET);
fread(starttab,tablen,1,inf);
fread(lengthtab,tablen,1,inf);
/* check data order */
cur = 0;
badorder = 0;
for(y=0; y<ysize; y++) {
for(z=0; z<zsize; z++) {
if(starttab[y+z*ysize]<cur) {
badorder = 1;
break;
}
cur = starttab[y+z*ysize];
}
if(badorder)
break;
}
fseek(inf,512+2*tablen,SEEK_SET);
cur = 512+2*tablen;
base = (unsigned long *)
malloc((xsize*ysize+TAGLEN)*sizeof(long));
addlongimgtag(base,xsize,ysize);
if(badorder) {
for(z=0; z<zsize; z++) {
lptr = base;
for(y=0; y<ysize; y++) {
if(cur != starttab[y+z*ysize]) {
fseek(inf,starttab[y+z*ysize],SEEK_SET);
cur = starttab[y+z*ysize];
}
if(lengthtab[y+z*ysize]>rlebuflen) {
fprintf(stderr,"longimagedata: rlebuf is too small - bad poop\n");
exit(1);
}
fread(rledat,lengthtab[y+z*ysize],1,inf);
cur += lengthtab[y+z*ysize];
expandrow(lptr,rledat,3-z);
lptr += xsize;
}
}
} else {
lptr = base;
for(y=0; y<ysize; y++) {
for(z=0; z<zsize; z++) {
if(cur != starttab[y+z*ysize]) {
fseek(inf,starttab[y+z*ysize],SEEK_SET);
cur = starttab[y+z*ysize];
}
fread(rledat,lengthtab[y+z*ysize],1,inf);
cur += lengthtab[y+z*ysize];
expandrow(lptr,rledat,3-z);
}
lptr += xsize;
}
}
if(zsize == 3)
setalpha(base,xsize*ysize);
else if(zsize<3)
copybw(base,xsize*ysize);
fclose(inf);
free(starttab);
free(lengthtab);
free(rledat);
free(image);
return base;
} else {
base = (unsigned long *)
malloc((xsize*ysize+TAGLEN)*sizeof(long));
addlongimgtag(base,xsize,ysize);
verdat = (unsigned char *)malloc(xsize);
fseek(inf,512,SEEK_SET);
for(z=0; z<zsize; z++) {
lptr = base;
for(y=0; y<ysize; y++) {
fread(verdat,xsize,1,inf);
interleaverow(lptr,verdat,3-z,xsize);
lptr += xsize;
}
}
if(zsize == 3)
setalpha(base,xsize*ysize);
else if(zsize<3)
copybw(base,xsize*ysize);
fclose(inf);
free(verdat);
free(image);
return base;
}
}
/* static utility functions for longimagedata */
static interleaverow(lptr,cptr,z,n)
unsigned char *lptr, *cptr;
int z, n;
{
lptr += z;
while(n--) {
*lptr = *cptr++;
lptr += 4;
}
}
static copybw(lptr,n)
long *lptr;
int n;
{
while(n>=8) {
lptr[0] = 0xff000000+(0x010101*(lptr[0]&0xff));
lptr[1] = 0xff000000+(0x010101*(lptr[1]&0xff));
lptr[2] = 0xff000000+(0x010101*(lptr[2]&0xff));
lptr[3] = 0xff000000+(0x010101*(lptr[3]&0xff));
lptr[4] = 0xff000000+(0x010101*(lptr[4]&0xff));
lptr[5] = 0xff000000+(0x010101*(lptr[5]&0xff));
lptr[6] = 0xff000000+(0x010101*(lptr[6]&0xff));
lptr[7] = 0xff000000+(0x010101*(lptr[7]&0xff));
lptr += 8;
n-=8;
}
while(n--) {
*lptr = 0xff000000+(0x010101*(*lptr&0xff));
lptr++;
}
}
static setalpha(lptr,n)
unsigned char *lptr;
{
while(n>=8) {
lptr[0*4] = 0xff;
lptr[1*4] = 0xff;
lptr[2*4] = 0xff;
lptr[3*4] = 0xff;
lptr[4*4] = 0xff;
lptr[5*4] = 0xff;
lptr[6*4] = 0xff;
lptr[7*4] = 0xff;
lptr += 4*8;
n -= 8;
}
while(n--) {
*lptr = 0xff;
lptr += 4;
}
}
static expandrow(optr,iptr,z)
unsigned char *optr, *iptr;
int z;
{
unsigned char pixel, count;
optr += z;
while(1) {
pixel = *iptr++;
if ( !(count = (pixel & 0x7f)) )
return;
if(pixel & 0x80) {
while(count>=8) {
optr[0*4] = iptr[0];
optr[1*4] = iptr[1];
optr[2*4] = iptr[2];
optr[3*4] = iptr[3];
optr[4*4] = iptr[4];
optr[5*4] = iptr[5];
optr[6*4] = iptr[6];
optr[7*4] = iptr[7];
optr += 8*4;
iptr += 8;
count -= 8;
}
while(count--) {
*optr = *iptr++;
optr+=4;
}
} else {
pixel = *iptr++;
while(count>=8) {
optr[0*4] = pixel;
optr[1*4] = pixel;
optr[2*4] = pixel;
optr[3*4] = pixel;
optr[4*4] = pixel;
optr[5*4] = pixel;
optr[6*4] = pixel;
optr[7*4] = pixel;
optr += 8*4;
count -= 8;
}
while(count--) {
*optr = pixel;
optr+=4;
}
}
}
}
/*
* addlongimgtag -
* this is used to extract image data from core dumps.
*
*/
addlongimgtag(dptr,xsize,ysize)
unsigned long *dptr;
int xsize, ysize;
{
dptr = dptr+(xsize*ysize);
dptr[0] = 0x12345678;
dptr[1] = 0x59493333;
dptr[2] = 0x69434222;
dptr[3] = xsize;
dptr[4] = ysize;
}